/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.yagnus.langutils.tuples;

/**
 * 
 * @author hc.busy
 * 
 *         Same as TwoTuple, exeption this one does a comparison between the two by comparing object
 *         a then object b;
 * 
 *         not null is greater than null without regard to native compareto result
 * 
 * 
 * @param <TA>
 *            a comparable type
 * @param <TB>
 *            a comparable type
 * 
 */
public class ComparableTwoTuple<TA extends Comparable<TA>, TB extends Comparable<TB>> extends TwoTuple<TA, TB>
                implements Comparable<TwoTuple<TA, TB>> {

    public ComparableTwoTuple(TA a, TB b) {
        super(a, b);
    }

    /**
     * 
     * convenience function for making a comparable two tupple
     * 
     * @param <TC>
     * @param <TD>
     * @param c
     * @param d
     * @return
     */
    public static <TC extends Comparable<TC>, TD extends Comparable<TD>> ComparableTwoTuple<TC, TD> make(TC c, TD d) {
        return new ComparableTwoTuple<TC, TD>(c, d);
    }

    /**
     * 
     * convenience function for making a comparable two tupple
     * 
     * @param <TC>
     * @param <TD>
     * @param c
     * @param d
     * @return
     */
    public static <TC extends Comparable<TC>, TD extends Comparable<TD>> ComparableTwoTuple<TC, TD> c(TC c, TD d) {
        return new ComparableTwoTuple<TC, TD>(c, d);
    }

    public int compareTo(TwoTuple<TA, TB> o) {

        if (a != null && o.a != null) {
            int ca = a.compareTo(o.a);
            if (ca != 0)
                return ca;
        } else if (a != null && o.a == null) {
            return 1; // a!=null o.a==null return I'm bigger
        } else if (a == null && o.a != null) {
            return -1; // a==null o.a!=null return I'm smaller
        }

        // get here only if a==o.a via nullness or compareTo==0
        if (b != null && o.b != null) {
            return b.compareTo(o.b);
        } else if (b != null && o.b == null) {
            return 1; // b==null o.b
        } else if (b == null && o.b != null) {
            return -1;
        } else {
            return 0;
        }
    }
}
